{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6924a68d-a3ed-4b44-8be8-96af69ad11e1",
   "metadata": {},
   "source": [
    "Chapter 18\n",
    "# 爱因斯坦求和约定\n",
    "Book_1《编程不难》 | 鸢尾花书：从加减乘除到机器学习  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5ee0093c-798e-4d8a-b813-a8544a652488",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入包\n",
    "import numpy as np\n",
    "from sklearn.datasets import load_iris"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "10049add-a590-423b-b4d0-480b2c7e35ca",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 从sklearn导入鸢尾花数据\n",
    "iris = load_iris()\n",
    "\n",
    "X = iris.data\n",
    "y = iris.target"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f9ce0ba-73c4-444c-94e9-ac52202793ff",
   "metadata": {},
   "source": [
    "## 求和"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "13d2c67b-ef51-45e2-a6ea-a5b74bab2995",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([876.5, 458.6, 563.7, 179.9])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 每一列求和\n",
    "np.einsum('ij->j',X)\n",
    "# np.sum(X, axis = 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a0b4fba5-bfea-415e-828d-584676238814",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([10.2,  9.5,  9.4,  9.4, 10.2, 11.4,  9.7, 10.1,  8.9,  9.6, 10.8,\n",
       "       10. ,  9.3,  8.5, 11.2, 12. , 11. , 10.3, 11.5, 10.7, 10.7, 10.7,\n",
       "        9.4, 10.6, 10.3,  9.8, 10.4, 10.4, 10.2,  9.7,  9.7, 10.7, 10.9,\n",
       "       11.3,  9.7,  9.6, 10.5, 10. ,  8.9, 10.2, 10.1,  8.4,  9.1, 10.7,\n",
       "       11.2,  9.5, 10.7,  9.4, 10.7,  9.9, 16.3, 15.6, 16.4, 13.1, 15.4,\n",
       "       14.3, 15.9, 11.6, 15.4, 13.2, 11.5, 14.6, 13.2, 15.1, 13.4, 15.6,\n",
       "       14.6, 13.6, 14.4, 13.1, 15.7, 14.2, 15.2, 14.8, 14.9, 15.4, 15.8,\n",
       "       16.4, 14.9, 12.8, 12.8, 12.6, 13.6, 15.4, 14.4, 15.5, 16. , 14.3,\n",
       "       14. , 13.3, 13.7, 15.1, 13.6, 11.6, 13.8, 14.1, 14.1, 14.7, 11.7,\n",
       "       13.9, 18.1, 15.5, 18.1, 16.6, 17.5, 19.3, 13.6, 18.3, 16.8, 19.4,\n",
       "       16.8, 16.3, 17.4, 15.2, 16.1, 17.2, 16.8, 20.4, 19.5, 14.7, 18.1,\n",
       "       15.3, 19.2, 15.7, 17.8, 18.2, 15.6, 15.8, 16.9, 17.6, 18.2, 20.1,\n",
       "       17. , 15.7, 15.7, 19.1, 17.7, 16.8, 15.6, 17.5, 17.8, 17.4, 15.5,\n",
       "       18.2, 18.2, 17.2, 15.7, 16.7, 17.3, 15.8])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 每一行求和\n",
    "np.einsum('ij->i',X)\n",
    "# np.sum(X, axis = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d581f2d9-0cbb-4c6d-b55d-f2ac1b4d0a7c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2078.6999999999994"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 矩阵所有元素求和\n",
    "np.einsum('ij->',X)\n",
    "# np.sum(X, axis = (0,1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "096e67ac-492b-4da1-8042-7597bb3265aa",
   "metadata": {},
   "source": [
    "## 转置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "59b2e7aa-2c62-4ade-9c9c-75cae74a5b22",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[5.1, 4.9, 4.7, 4.6, 5. , 5.4, 4.6, 5. , 4.4, 4.9, 5.4, 4.8, 4.8,\n",
       "        4.3, 5.8, 5.7, 5.4, 5.1, 5.7, 5.1, 5.4, 5.1, 4.6, 5.1, 4.8, 5. ,\n",
       "        5. , 5.2, 5.2, 4.7, 4.8, 5.4, 5.2, 5.5, 4.9, 5. , 5.5, 4.9, 4.4,\n",
       "        5.1, 5. , 4.5, 4.4, 5. , 5.1, 4.8, 5.1, 4.6, 5.3, 5. , 7. , 6.4,\n",
       "        6.9, 5.5, 6.5, 5.7, 6.3, 4.9, 6.6, 5.2, 5. , 5.9, 6. , 6.1, 5.6,\n",
       "        6.7, 5.6, 5.8, 6.2, 5.6, 5.9, 6.1, 6.3, 6.1, 6.4, 6.6, 6.8, 6.7,\n",
       "        6. , 5.7, 5.5, 5.5, 5.8, 6. , 5.4, 6. , 6.7, 6.3, 5.6, 5.5, 5.5,\n",
       "        6.1, 5.8, 5. , 5.6, 5.7, 5.7, 6.2, 5.1, 5.7, 6.3, 5.8, 7.1, 6.3,\n",
       "        6.5, 7.6, 4.9, 7.3, 6.7, 7.2, 6.5, 6.4, 6.8, 5.7, 5.8, 6.4, 6.5,\n",
       "        7.7, 7.7, 6. , 6.9, 5.6, 7.7, 6.3, 6.7, 7.2, 6.2, 6.1, 6.4, 7.2,\n",
       "        7.4, 7.9, 6.4, 6.3, 6.1, 7.7, 6.3, 6.4, 6. , 6.9, 6.7, 6.9, 5.8,\n",
       "        6.8, 6.7, 6.7, 6.3, 6.5, 6.2, 5.9],\n",
       "       [3.5, 3. , 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.4, 3. ,\n",
       "        3. , 4. , 4.4, 3.9, 3.5, 3.8, 3.8, 3.4, 3.7, 3.6, 3.3, 3.4, 3. ,\n",
       "        3.4, 3.5, 3.4, 3.2, 3.1, 3.4, 4.1, 4.2, 3.1, 3.2, 3.5, 3.6, 3. ,\n",
       "        3.4, 3.5, 2.3, 3.2, 3.5, 3.8, 3. , 3.8, 3.2, 3.7, 3.3, 3.2, 3.2,\n",
       "        3.1, 2.3, 2.8, 2.8, 3.3, 2.4, 2.9, 2.7, 2. , 3. , 2.2, 2.9, 2.9,\n",
       "        3.1, 3. , 2.7, 2.2, 2.5, 3.2, 2.8, 2.5, 2.8, 2.9, 3. , 2.8, 3. ,\n",
       "        2.9, 2.6, 2.4, 2.4, 2.7, 2.7, 3. , 3.4, 3.1, 2.3, 3. , 2.5, 2.6,\n",
       "        3. , 2.6, 2.3, 2.7, 3. , 2.9, 2.9, 2.5, 2.8, 3.3, 2.7, 3. , 2.9,\n",
       "        3. , 3. , 2.5, 2.9, 2.5, 3.6, 3.2, 2.7, 3. , 2.5, 2.8, 3.2, 3. ,\n",
       "        3.8, 2.6, 2.2, 3.2, 2.8, 2.8, 2.7, 3.3, 3.2, 2.8, 3. , 2.8, 3. ,\n",
       "        2.8, 3.8, 2.8, 2.8, 2.6, 3. , 3.4, 3.1, 3. , 3.1, 3.1, 3.1, 2.7,\n",
       "        3.2, 3.3, 3. , 2.5, 3. , 3.4, 3. ],\n",
       "       [1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, 1.5, 1.6, 1.4,\n",
       "        1.1, 1.2, 1.5, 1.3, 1.4, 1.7, 1.5, 1.7, 1.5, 1. , 1.7, 1.9, 1.6,\n",
       "        1.6, 1.5, 1.4, 1.6, 1.6, 1.5, 1.5, 1.4, 1.5, 1.2, 1.3, 1.4, 1.3,\n",
       "        1.5, 1.3, 1.3, 1.3, 1.6, 1.9, 1.4, 1.6, 1.4, 1.5, 1.4, 4.7, 4.5,\n",
       "        4.9, 4. , 4.6, 4.5, 4.7, 3.3, 4.6, 3.9, 3.5, 4.2, 4. , 4.7, 3.6,\n",
       "        4.4, 4.5, 4.1, 4.5, 3.9, 4.8, 4. , 4.9, 4.7, 4.3, 4.4, 4.8, 5. ,\n",
       "        4.5, 3.5, 3.8, 3.7, 3.9, 5.1, 4.5, 4.5, 4.7, 4.4, 4.1, 4. , 4.4,\n",
       "        4.6, 4. , 3.3, 4.2, 4.2, 4.2, 4.3, 3. , 4.1, 6. , 5.1, 5.9, 5.6,\n",
       "        5.8, 6.6, 4.5, 6.3, 5.8, 6.1, 5.1, 5.3, 5.5, 5. , 5.1, 5.3, 5.5,\n",
       "        6.7, 6.9, 5. , 5.7, 4.9, 6.7, 4.9, 5.7, 6. , 4.8, 4.9, 5.6, 5.8,\n",
       "        6.1, 6.4, 5.6, 5.1, 5.6, 6.1, 5.6, 5.5, 4.8, 5.4, 5.6, 5.1, 5.1,\n",
       "        5.9, 5.7, 5.2, 5. , 5.2, 5.4, 5.1],\n",
       "       [0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1,\n",
       "        0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2,\n",
       "        0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2,\n",
       "        0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2, 1.4, 1.5,\n",
       "        1.5, 1.3, 1.5, 1.3, 1.6, 1. , 1.3, 1.4, 1. , 1.5, 1. , 1.4, 1.3,\n",
       "        1.4, 1.5, 1. , 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7,\n",
       "        1.5, 1. , 1.1, 1. , 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2,\n",
       "        1.4, 1.2, 1. , 1.3, 1.2, 1.3, 1.3, 1.1, 1.3, 2.5, 1.9, 2.1, 1.8,\n",
       "        2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2. , 1.9, 2.1, 2. , 2.4, 2.3, 1.8,\n",
       "        2.2, 2.3, 1.5, 2.3, 2. , 2. , 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6,\n",
       "        1.9, 2. , 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9,\n",
       "        2.3, 2.5, 2.3, 1.9, 2. , 2.3, 1.8]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 二维数组转置\n",
    "np.einsum('ij->ji',X)\n",
    "# X.T\n",
    "# np.transpose(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "3fcfce07-541a-4982-96db-bbdc603aabb4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[5.1, 3.5, 1.4, 0.2],\n",
       "        [4.9, 3. , 1.4, 0.2],\n",
       "        [4.7, 3.2, 1.3, 0.2],\n",
       "        [4.6, 3.1, 1.5, 0.2],\n",
       "        [5. , 3.6, 1.4, 0.2],\n",
       "        [5.4, 3.9, 1.7, 0.4],\n",
       "        [4.6, 3.4, 1.4, 0.3],\n",
       "        [5. , 3.4, 1.5, 0.2],\n",
       "        [4.4, 2.9, 1.4, 0.2],\n",
       "        [4.9, 3.1, 1.5, 0.1],\n",
       "        [5.4, 3.7, 1.5, 0.2],\n",
       "        [4.8, 3.4, 1.6, 0.2],\n",
       "        [4.8, 3. , 1.4, 0.1],\n",
       "        [4.3, 3. , 1.1, 0.1],\n",
       "        [5.8, 4. , 1.2, 0.2],\n",
       "        [5.7, 4.4, 1.5, 0.4],\n",
       "        [5.4, 3.9, 1.3, 0.4],\n",
       "        [5.1, 3.5, 1.4, 0.3],\n",
       "        [5.7, 3.8, 1.7, 0.3],\n",
       "        [5.1, 3.8, 1.5, 0.3],\n",
       "        [5.4, 3.4, 1.7, 0.2],\n",
       "        [5.1, 3.7, 1.5, 0.4],\n",
       "        [4.6, 3.6, 1. , 0.2],\n",
       "        [5.1, 3.3, 1.7, 0.5],\n",
       "        [4.8, 3.4, 1.9, 0.2],\n",
       "        [5. , 3. , 1.6, 0.2],\n",
       "        [5. , 3.4, 1.6, 0.4],\n",
       "        [5.2, 3.5, 1.5, 0.2],\n",
       "        [5.2, 3.4, 1.4, 0.2],\n",
       "        [4.7, 3.2, 1.6, 0.2],\n",
       "        [4.8, 3.1, 1.6, 0.2],\n",
       "        [5.4, 3.4, 1.5, 0.4],\n",
       "        [5.2, 4.1, 1.5, 0.1],\n",
       "        [5.5, 4.2, 1.4, 0.2],\n",
       "        [4.9, 3.1, 1.5, 0.2],\n",
       "        [5. , 3.2, 1.2, 0.2],\n",
       "        [5.5, 3.5, 1.3, 0.2],\n",
       "        [4.9, 3.6, 1.4, 0.1],\n",
       "        [4.4, 3. , 1.3, 0.2],\n",
       "        [5.1, 3.4, 1.5, 0.2],\n",
       "        [5. , 3.5, 1.3, 0.3],\n",
       "        [4.5, 2.3, 1.3, 0.3],\n",
       "        [4.4, 3.2, 1.3, 0.2],\n",
       "        [5. , 3.5, 1.6, 0.6],\n",
       "        [5.1, 3.8, 1.9, 0.4],\n",
       "        [4.8, 3. , 1.4, 0.3],\n",
       "        [5.1, 3.8, 1.6, 0.2],\n",
       "        [4.6, 3.2, 1.4, 0.2],\n",
       "        [5.3, 3.7, 1.5, 0.2],\n",
       "        [5. , 3.3, 1.4, 0.2]],\n",
       "\n",
       "       [[7. , 3.2, 4.7, 1.4],\n",
       "        [6.4, 3.2, 4.5, 1.5],\n",
       "        [6.9, 3.1, 4.9, 1.5],\n",
       "        [5.5, 2.3, 4. , 1.3],\n",
       "        [6.5, 2.8, 4.6, 1.5],\n",
       "        [5.7, 2.8, 4.5, 1.3],\n",
       "        [6.3, 3.3, 4.7, 1.6],\n",
       "        [4.9, 2.4, 3.3, 1. ],\n",
       "        [6.6, 2.9, 4.6, 1.3],\n",
       "        [5.2, 2.7, 3.9, 1.4],\n",
       "        [5. , 2. , 3.5, 1. ],\n",
       "        [5.9, 3. , 4.2, 1.5],\n",
       "        [6. , 2.2, 4. , 1. ],\n",
       "        [6.1, 2.9, 4.7, 1.4],\n",
       "        [5.6, 2.9, 3.6, 1.3],\n",
       "        [6.7, 3.1, 4.4, 1.4],\n",
       "        [5.6, 3. , 4.5, 1.5],\n",
       "        [5.8, 2.7, 4.1, 1. ],\n",
       "        [6.2, 2.2, 4.5, 1.5],\n",
       "        [5.6, 2.5, 3.9, 1.1],\n",
       "        [5.9, 3.2, 4.8, 1.8],\n",
       "        [6.1, 2.8, 4. , 1.3],\n",
       "        [6.3, 2.5, 4.9, 1.5],\n",
       "        [6.1, 2.8, 4.7, 1.2],\n",
       "        [6.4, 2.9, 4.3, 1.3],\n",
       "        [6.6, 3. , 4.4, 1.4],\n",
       "        [6.8, 2.8, 4.8, 1.4],\n",
       "        [6.7, 3. , 5. , 1.7],\n",
       "        [6. , 2.9, 4.5, 1.5],\n",
       "        [5.7, 2.6, 3.5, 1. ],\n",
       "        [5.5, 2.4, 3.8, 1.1],\n",
       "        [5.5, 2.4, 3.7, 1. ],\n",
       "        [5.8, 2.7, 3.9, 1.2],\n",
       "        [6. , 2.7, 5.1, 1.6],\n",
       "        [5.4, 3. , 4.5, 1.5],\n",
       "        [6. , 3.4, 4.5, 1.6],\n",
       "        [6.7, 3.1, 4.7, 1.5],\n",
       "        [6.3, 2.3, 4.4, 1.3],\n",
       "        [5.6, 3. , 4.1, 1.3],\n",
       "        [5.5, 2.5, 4. , 1.3],\n",
       "        [5.5, 2.6, 4.4, 1.2],\n",
       "        [6.1, 3. , 4.6, 1.4],\n",
       "        [5.8, 2.6, 4. , 1.2],\n",
       "        [5. , 2.3, 3.3, 1. ],\n",
       "        [5.6, 2.7, 4.2, 1.3],\n",
       "        [5.7, 3. , 4.2, 1.2],\n",
       "        [5.7, 2.9, 4.2, 1.3],\n",
       "        [6.2, 2.9, 4.3, 1.3],\n",
       "        [5.1, 2.5, 3. , 1.1],\n",
       "        [5.7, 2.8, 4.1, 1.3]],\n",
       "\n",
       "       [[6.3, 3.3, 6. , 2.5],\n",
       "        [5.8, 2.7, 5.1, 1.9],\n",
       "        [7.1, 3. , 5.9, 2.1],\n",
       "        [6.3, 2.9, 5.6, 1.8],\n",
       "        [6.5, 3. , 5.8, 2.2],\n",
       "        [7.6, 3. , 6.6, 2.1],\n",
       "        [4.9, 2.5, 4.5, 1.7],\n",
       "        [7.3, 2.9, 6.3, 1.8],\n",
       "        [6.7, 2.5, 5.8, 1.8],\n",
       "        [7.2, 3.6, 6.1, 2.5],\n",
       "        [6.5, 3.2, 5.1, 2. ],\n",
       "        [6.4, 2.7, 5.3, 1.9],\n",
       "        [6.8, 3. , 5.5, 2.1],\n",
       "        [5.7, 2.5, 5. , 2. ],\n",
       "        [5.8, 2.8, 5.1, 2.4],\n",
       "        [6.4, 3.2, 5.3, 2.3],\n",
       "        [6.5, 3. , 5.5, 1.8],\n",
       "        [7.7, 3.8, 6.7, 2.2],\n",
       "        [7.7, 2.6, 6.9, 2.3],\n",
       "        [6. , 2.2, 5. , 1.5],\n",
       "        [6.9, 3.2, 5.7, 2.3],\n",
       "        [5.6, 2.8, 4.9, 2. ],\n",
       "        [7.7, 2.8, 6.7, 2. ],\n",
       "        [6.3, 2.7, 4.9, 1.8],\n",
       "        [6.7, 3.3, 5.7, 2.1],\n",
       "        [7.2, 3.2, 6. , 1.8],\n",
       "        [6.2, 2.8, 4.8, 1.8],\n",
       "        [6.1, 3. , 4.9, 1.8],\n",
       "        [6.4, 2.8, 5.6, 2.1],\n",
       "        [7.2, 3. , 5.8, 1.6],\n",
       "        [7.4, 2.8, 6.1, 1.9],\n",
       "        [7.9, 3.8, 6.4, 2. ],\n",
       "        [6.4, 2.8, 5.6, 2.2],\n",
       "        [6.3, 2.8, 5.1, 1.5],\n",
       "        [6.1, 2.6, 5.6, 1.4],\n",
       "        [7.7, 3. , 6.1, 2.3],\n",
       "        [6.3, 3.4, 5.6, 2.4],\n",
       "        [6.4, 3.1, 5.5, 1.8],\n",
       "        [6. , 3. , 4.8, 1.8],\n",
       "        [6.9, 3.1, 5.4, 2.1],\n",
       "        [6.7, 3.1, 5.6, 2.4],\n",
       "        [6.9, 3.1, 5.1, 2.3],\n",
       "        [5.8, 2.7, 5.1, 1.9],\n",
       "        [6.8, 3.2, 5.9, 2.3],\n",
       "        [6.7, 3.3, 5.7, 2.5],\n",
       "        [6.7, 3. , 5.2, 2.3],\n",
       "        [6.3, 2.5, 5. , 1.9],\n",
       "        [6.5, 3. , 5.2, 2. ],\n",
       "        [6.2, 3.4, 5.4, 2.3],\n",
       "        [5.9, 3. , 5.1, 1.8]]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 三维数组\n",
    "X3D = np.stack([X[y == 0], X[y == 1], X[y == 2]], axis=0)\n",
    "X3D"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "3438ef65-8609-43a6-85a6-77e78ca2f9fb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3, 50, 4)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X3D.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "6874289d-1297-4210-92b7-b828c74ee36e",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[5.1, 4.9, 4.7, 4.6, 5. , 5.4, 4.6, 5. , 4.4, 4.9, 5.4, 4.8,\n",
       "         4.8, 4.3, 5.8, 5.7, 5.4, 5.1, 5.7, 5.1, 5.4, 5.1, 4.6, 5.1,\n",
       "         4.8, 5. , 5. , 5.2, 5.2, 4.7, 4.8, 5.4, 5.2, 5.5, 4.9, 5. ,\n",
       "         5.5, 4.9, 4.4, 5.1, 5. , 4.5, 4.4, 5. , 5.1, 4.8, 5.1, 4.6,\n",
       "         5.3, 5. ],\n",
       "        [3.5, 3. , 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.4,\n",
       "         3. , 3. , 4. , 4.4, 3.9, 3.5, 3.8, 3.8, 3.4, 3.7, 3.6, 3.3,\n",
       "         3.4, 3. , 3.4, 3.5, 3.4, 3.2, 3.1, 3.4, 4.1, 4.2, 3.1, 3.2,\n",
       "         3.5, 3.6, 3. , 3.4, 3.5, 2.3, 3.2, 3.5, 3.8, 3. , 3.8, 3.2,\n",
       "         3.7, 3.3],\n",
       "        [1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, 1.5, 1.6,\n",
       "         1.4, 1.1, 1.2, 1.5, 1.3, 1.4, 1.7, 1.5, 1.7, 1.5, 1. , 1.7,\n",
       "         1.9, 1.6, 1.6, 1.5, 1.4, 1.6, 1.6, 1.5, 1.5, 1.4, 1.5, 1.2,\n",
       "         1.3, 1.4, 1.3, 1.5, 1.3, 1.3, 1.3, 1.6, 1.9, 1.4, 1.6, 1.4,\n",
       "         1.5, 1.4],\n",
       "        [0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2,\n",
       "         0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5,\n",
       "         0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2,\n",
       "         0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2,\n",
       "         0.2, 0.2]],\n",
       "\n",
       "       [[7. , 6.4, 6.9, 5.5, 6.5, 5.7, 6.3, 4.9, 6.6, 5.2, 5. , 5.9,\n",
       "         6. , 6.1, 5.6, 6.7, 5.6, 5.8, 6.2, 5.6, 5.9, 6.1, 6.3, 6.1,\n",
       "         6.4, 6.6, 6.8, 6.7, 6. , 5.7, 5.5, 5.5, 5.8, 6. , 5.4, 6. ,\n",
       "         6.7, 6.3, 5.6, 5.5, 5.5, 6.1, 5.8, 5. , 5.6, 5.7, 5.7, 6.2,\n",
       "         5.1, 5.7],\n",
       "        [3.2, 3.2, 3.1, 2.3, 2.8, 2.8, 3.3, 2.4, 2.9, 2.7, 2. , 3. ,\n",
       "         2.2, 2.9, 2.9, 3.1, 3. , 2.7, 2.2, 2.5, 3.2, 2.8, 2.5, 2.8,\n",
       "         2.9, 3. , 2.8, 3. , 2.9, 2.6, 2.4, 2.4, 2.7, 2.7, 3. , 3.4,\n",
       "         3.1, 2.3, 3. , 2.5, 2.6, 3. , 2.6, 2.3, 2.7, 3. , 2.9, 2.9,\n",
       "         2.5, 2.8],\n",
       "        [4.7, 4.5, 4.9, 4. , 4.6, 4.5, 4.7, 3.3, 4.6, 3.9, 3.5, 4.2,\n",
       "         4. , 4.7, 3.6, 4.4, 4.5, 4.1, 4.5, 3.9, 4.8, 4. , 4.9, 4.7,\n",
       "         4.3, 4.4, 4.8, 5. , 4.5, 3.5, 3.8, 3.7, 3.9, 5.1, 4.5, 4.5,\n",
       "         4.7, 4.4, 4.1, 4. , 4.4, 4.6, 4. , 3.3, 4.2, 4.2, 4.2, 4.3,\n",
       "         3. , 4.1],\n",
       "        [1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1. , 1.3, 1.4, 1. , 1.5,\n",
       "         1. , 1.4, 1.3, 1.4, 1.5, 1. , 1.5, 1.1, 1.8, 1.3, 1.5, 1.2,\n",
       "         1.3, 1.4, 1.4, 1.7, 1.5, 1. , 1.1, 1. , 1.2, 1.6, 1.5, 1.6,\n",
       "         1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1. , 1.3, 1.2, 1.3, 1.3,\n",
       "         1.1, 1.3]],\n",
       "\n",
       "       [[6.3, 5.8, 7.1, 6.3, 6.5, 7.6, 4.9, 7.3, 6.7, 7.2, 6.5, 6.4,\n",
       "         6.8, 5.7, 5.8, 6.4, 6.5, 7.7, 7.7, 6. , 6.9, 5.6, 7.7, 6.3,\n",
       "         6.7, 7.2, 6.2, 6.1, 6.4, 7.2, 7.4, 7.9, 6.4, 6.3, 6.1, 7.7,\n",
       "         6.3, 6.4, 6. , 6.9, 6.7, 6.9, 5.8, 6.8, 6.7, 6.7, 6.3, 6.5,\n",
       "         6.2, 5.9],\n",
       "        [3.3, 2.7, 3. , 2.9, 3. , 3. , 2.5, 2.9, 2.5, 3.6, 3.2, 2.7,\n",
       "         3. , 2.5, 2.8, 3.2, 3. , 3.8, 2.6, 2.2, 3.2, 2.8, 2.8, 2.7,\n",
       "         3.3, 3.2, 2.8, 3. , 2.8, 3. , 2.8, 3.8, 2.8, 2.8, 2.6, 3. ,\n",
       "         3.4, 3.1, 3. , 3.1, 3.1, 3.1, 2.7, 3.2, 3.3, 3. , 2.5, 3. ,\n",
       "         3.4, 3. ],\n",
       "        [6. , 5.1, 5.9, 5.6, 5.8, 6.6, 4.5, 6.3, 5.8, 6.1, 5.1, 5.3,\n",
       "         5.5, 5. , 5.1, 5.3, 5.5, 6.7, 6.9, 5. , 5.7, 4.9, 6.7, 4.9,\n",
       "         5.7, 6. , 4.8, 4.9, 5.6, 5.8, 6.1, 6.4, 5.6, 5.1, 5.6, 6.1,\n",
       "         5.6, 5.5, 4.8, 5.4, 5.6, 5.1, 5.1, 5.9, 5.7, 5.2, 5. , 5.2,\n",
       "         5.4, 5.1],\n",
       "        [2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2. , 1.9,\n",
       "         2.1, 2. , 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2. , 2. , 1.8,\n",
       "         2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2. , 2.2, 1.5, 1.4, 2.3,\n",
       "         2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2. ,\n",
       "         2.3, 1.8]]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X3D_T = np.einsum('ijk->ikj', X3D)\n",
    "X3D_T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "ae53f96a-0c56-42f0-ae28-2770c5f35c0b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3, 4, 50)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "T_3D = np.transpose(X3D,(0, 2, 1))\n",
    "T_3D.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f0b3bb4-8dfa-4a46-8dda-d1309ce2ecfd",
   "metadata": {},
   "source": [
    "## 格拉姆矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "357f4400-4f0a-43f9-a0a4-dfc63e1e9b6d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[40.26, 37.49, 37.03, ..., 51.33, 51.54, 48.09],\n",
       "       [37.49, 35.01, 34.49, ..., 48.53, 48.6 , 45.41],\n",
       "       [37.03, 34.49, 34.06, ..., 47.31, 47.5 , 44.32],\n",
       "       ...,\n",
       "       [51.33, 48.53, 47.31, ..., 82.29, 83.18, 77.47],\n",
       "       [51.54, 48.6 , 47.5 , ..., 83.18, 84.45, 78.46],\n",
       "       [48.09, 45.41, 44.32, ..., 77.47, 78.46, 73.06]])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算矩阵乘法 X @ X.T\n",
    "np.einsum('ij,kj->ik', X, X)\n",
    "# np.einsum('ij,jk->ik', X, X.T)\n",
    "# X @ X.T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "f630ce5e-dbee-4a77-a934-6bf47eb0bd07",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算矩阵乘法 X.T @ X\n",
    "G = np.einsum('ij,ik->jk', X, X)\n",
    "# np.einsum('ij,jk->ik', X.T, X)\n",
    "# X.T @ X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "4191206d-8497-4ee6-b042-1f0b6ffa4116",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[1259.09,  862.89,  366.74,   62.08],\n",
       "        [ 862.89,  594.6 ,  251.16,   42.62],\n",
       "        [ 366.74,  251.16,  108.35,   18.28],\n",
       "        [  62.08,   42.62,   18.28,    3.57]],\n",
       "\n",
       "       [[1774.86,  826.31, 1273.33,  396.29],\n",
       "        [ 826.31,  388.47,  594.06,  185.67],\n",
       "        [1273.33,  594.06,  918.2 ,  286.02],\n",
       "        [ 396.29,  185.67,  286.02,   89.83]],\n",
       "\n",
       "       [[2189.9 ,  984.23, 1843.69,  669.77],\n",
       "        [ 984.23,  447.33,  829.08,  303.6 ],\n",
       "        [1843.69,  829.08, 1556.16,  564.81],\n",
       "        [ 669.77,  303.6 ,  564.81,  208.93]]])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 三维矩阵乘法\n",
    "# np.einsum('mij,mjk->mik', X3D_T, X3D)\n",
    "G_3D = np.einsum('ijk,ijm->ikm', X3D, X3D)\n",
    "G_3D"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1dad6cdc-2960-4032-bc26-72b5d5d38990",
   "metadata": {},
   "source": [
    "## 一维数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "152808a0-a608-4b18-a455-f7db4b0cb7c7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 提取两个行向量\n",
    "a_1D = X[0]\n",
    "b_1D = X[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "eb00faac-913c-40a9-832e-6c07b946c6b2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10.2"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 一维向量求和\n",
    "np.einsum('i->',a_1D)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "fd8c9364-4661-4aff-bc80-44983721bb9f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[24.99 10.5   1.96  0.04]\n"
     ]
    }
   ],
   "source": [
    "# 一维向量逐项积\n",
    "print(np.einsum('i,i->i',a_1D,b_1D))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "247bec76-2092-4ed2-ae58-307f5acba845",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "37.489999999999995\n"
     ]
    }
   ],
   "source": [
    "# 一维向量内积\n",
    "print(np.einsum('i,i->',a_1D,b_1D))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "11f89beb-781b-479b-9433-d94788766b08",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[24.99 15.3   7.14  1.02]\n",
      " [17.15 10.5   4.9   0.7 ]\n",
      " [ 6.86  4.2   1.96  0.28]\n",
      " [ 0.98  0.6   0.28  0.04]]\n"
     ]
    }
   ],
   "source": [
    "# 一维向量外积\n",
    "print(np.einsum('i,j->ij',a_1D,b_1D))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42a349a0-054a-4af0-8874-f503620da78f",
   "metadata": {},
   "source": [
    "## 对角方阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "04c6c50d-cf46-4c67-884b-c8f551c26b6d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5223.85, 1430.4 , 2582.71,  302.33])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#%% 取出方阵对角\n",
    "np.einsum('ii->i',G)\n",
    "# np.diag(G)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "c068ac00-c2b6-430f-9374-3d5d22cf90b5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5223.85, 1430.4 , 2582.71,  302.33])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.diag(G)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "6d855071-1159-42c6-84c2-f23bbcd4968a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "9539.289999999997"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#%% 计算方阵迹\n",
    "np.einsum('ii->',G)\n",
    "# np.trace(G)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67b24187-d3f8-46f6-8fbb-985e35465803",
   "metadata": {},
   "source": [
    "## 统计"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "3f644ad3-5691-42cc-8372-60ca5c1e5af1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算列均值，质心\n",
    "n = X.shape[0]  # 样本数量\n",
    "mean_X = np.einsum('ij->j', X) / n\n",
    "# np.mean(X, axis = 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "86be55e9-d7fb-4082-b8b3-a3eb35d17007",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5.84333333, 3.05733333, 3.758     , 1.19933333])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "d24d559c-9a9b-4fdf-941d-7548a145ffc8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算方差\n",
    "X_c = X - mean_X  # 中心化数据\n",
    "variance = np.einsum('ij,ij->j', X_c, X_c) / (n - 1)\n",
    "# np.var(X, axis = 0, ddof = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "9837096f-7810-4063-afae-a61c7934513a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.68569351, 0.18997942, 3.11627785, 0.58100626])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "variance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "326e687d-4f2f-4cda-a50f-26c0bbe6295d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算协方差矩阵\n",
    "cov_matrix = np.einsum('ij,ik->jk', X_c, X_c) / (n - 1)\n",
    "# np.cov(X.T, ddof = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "109353e4-d77d-42a9-98c7-6dee7c9be067",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.68569351, -0.042434  ,  1.27431544,  0.51627069],\n",
       "       [-0.042434  ,  0.18997942, -0.32965638, -0.12163937],\n",
       "       [ 1.27431544, -0.32965638,  3.11627785,  1.2956094 ],\n",
       "       [ 0.51627069, -0.12163937,  1.2956094 ,  0.58100626]])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cov_matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "1b6f1927-8b65-488b-8137-7aedeefe67ec",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.68569351, -0.042434  ,  1.27431544,  0.51627069],\n",
       "       [-0.042434  ,  0.18997942, -0.32965638, -0.12163937],\n",
       "       [ 1.27431544, -0.32965638,  3.11627785,  1.2956094 ],\n",
       "       [ 0.51627069, -0.12163937,  1.2956094 ,  0.58100626]])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.cov(X.T, ddof = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "1e35da1f-5d4b-4f26-9f6a-61faeacf7453",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[5.006, 3.428, 1.462, 0.246],\n",
       "       [5.936, 2.77 , 4.26 , 1.326],\n",
       "       [6.588, 2.974, 5.552, 2.026]])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算分类协方差\n",
    "X3D_mean = np.mean(X3D, axis = 1)\n",
    "X3D_mean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "33089a1e-8227-4e6e-b54a-4a4ed925b51b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
